#pragma once
#include<iostream>
#include<string>
#include<poll.h>
#include<memory>
#include"Log.hpp"
#include"Socket.hpp"

using namespace Net_Work;

const static int gdefaultport = 8888;//默认端口
const static int gbacklog = 8;
const static int gnum = 1024;
const static int gdefaultfd = -1;//默认文件描述符-1
const static int gdefultevent = 0;
class PollServer
{
    public:
        PollServer(int port = gdefaultport)
        :_port(port),
        _listensock(new  Tcpsocket()),
        _isrunning(false),
        _timeout(-1)
        {}
        void handlerEvents()
        {
            for (int i = 0; i < gnum; i++)
            {
                if (_events[i].fd == gdefaultfd)
                    continue;
                int fd = _events[i].fd;
                short revents = _events[i].revents;
                if (revents & POLLIN)
                {
                    if (fd == _listensock->GetSockFd())
                    {
                        // 新连接
                        std::string clientip;
                        uint16_t clientport;
                        int sockfd = _listensock->AcceptConnection(&clientip, &clientport);
                        if (sockfd < 0)
                            continue;
                        lg.logMessage(DEBUG, "get anew client %s:%d\n", clientip.c_str(), clientport);
                        int j = 0;
                        for (; j < gnum; j++)
                        {
                            if (_events[j].fd == gdefaultfd)
                            {
                                break;
                            }
                        }
                        if (j < gnum)
                        {
                            // 给poll添加新的sockfd
                            _events[j].fd = sockfd;
                            _events[j].events = POLLIN;
                            _events[j].revents = gdefultevent;
                            lg.logMessage(DEBUG, "add a new client ,fd is:%d\n", sockfd);
                            PrintDebug();
                        }
                        else
                        {
                            
                        }
                    }
                    else
                    {
                        char buffer[1024];
                        //读事件就绪
                        ssize_t n = recv(fd,buffer,sizeof(buffer)-1,0);
                        if(n>0)
                        {
                            buffer[n] = 0;
                            lg.logMessage(DEBUG,"client info# %s\n",buffer);
                            std::string echo_message = "[server echo]# ";
                            echo_message+=buffer;
                            send(fd,echo_message.c_str(),echo_message.size(),0);
                        }
                        else if(n==0)
                        {
                            ::close(fd);
                            _events[i].fd = gdefaultfd;
                            _events[i].events = _events[i].revents = gdefultevent;
                            lg.logMessage(INFO,"client quit...,remove fd:%d\n",fd);
                            PrintDebug();
                        }
                        else
                        {
                            ::close(fd);
                            _events[i].fd = gdefaultfd;
                            _events[i].events = _events[i].revents = gdefultevent;
                            lg.logMessage(INFO,"recv error...,remove fd:%d\n",fd);
                            PrintDebug();
                        }
                    }
                }
                if(revents&POLLOUT)
                {
                    
                }
            }
        }
        void InitServer()
        { 
            _listensock->BuildlistenSocketMethod(_port,gbacklog);
            for(int i = 0;i<gnum;i++)
            {
                _events[i].fd = gdefaultfd;
                _events[i].events = gdefultevent;
                _events[i].revents = gdefultevent;
            }
            _events[0].fd = _listensock->GetSockFd();
            _events[0].events = POLLIN;//对读事件关心，(listensock上有新连接，就是都事件就绪)
            lg.logMessage(DEBUG,"add listen socket fd is:%d\n",_listensock->GetSockFd());
        }
        void  Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                int n = poll(_events,gnum,_timeout);
                switch (n)
                {
                case 0:
                   lg.logMessage(INFO,"poll timeout..\n");
                    break;
                case -1:
                    lg.logMessage(ERROR,"poll error\n");
                    break;
                default:
                    //正常的就绪的fd
                    lg.logMessage(INFO,"get a read event\n");//读取事件
                    handlerEvents();
                    break;
                }
            }
            _isrunning = false;
        }
        void Stop()
        {
            _isrunning = false;
        }
        void PrintDebug()
        {
            std::cout<<"current poll rfds list is :";
            for(int i = 0;i<gnum;i++)
            {
                if(_events[i].fd == gdefaultfd)
                continue;
                else
                
                    std::cout<<_events[i].fd<<" ";
                
            }
            std::cout<<std::endl;
        }
        ~PollServer()
        {

        }

    private:
    std::unique_ptr<Socket> _listensock;
    int _port;
    int _isrunning;
    struct pollfd _events[gnum];
    int _timeout;
};
